#include<stdio.h>
#include<ctime>
#include<cstdlib>
#include "nature.h"

using namespace std;

Creature::Creature(){}

Creature::Creature(int name){}

Creature::Creature(int name,int x, int y, Flag flag)
{

}

Creature::~Creature(){}
/*判断生理状况并确定行动模式*/
int Creature::situation()
{
	int temp;
	if (m_hp <= 0)
	{
		if (m_hunger <= 0)
		{
			m_flag.dead = 3;
		}
		else
		{
			m_flag.dead = 2;
		}
		m_flag.can_eat = 2;/*死掉的对象不能吃*/
		record();
		return m_flag.live = 2;
	}/*重伤则死,生成记录并退出函数*/
	if (nature.time_past % 10 == 0)
	{
		m_age++;
	}/*年龄增长，每10time年龄加一*/
	if (m_age >= m_flag.age_up)
	{
		m_flag.dead = 1;
		record();
		return m_flag.live = 2;
	}
	/*到寿则死，生成记录并退出函数*/
	if (m_hunger <= 20)
	{
		temp = 20 - m_hunger;
		m_hunger = 0;
		m_hp -= temp;
	}/*当饥饿值不够时扣除血量*/
	else
	{
		m_hunger -= 20;
	}/*正常消耗,一次20*/
	if (m_hp <= m_flag.hp_up)
	{
		temp = m_flag.hp_up - m_hp;
		if (temp <= 20)
		{
			m_hunger -= temp;
			m_hp += temp;
		}
		else
		{
			m_hunger -= 20;
			m_hp += 20;
		}
	}/*如果受伤则额外消耗能量疗伤*/
	if (m_hunger >= 80)/*满血的同时还能支持4回合不吃不喝行动则进入繁衍*/
	{
		return m_flag.mode = 2;
	}
	return m_flag.mode = 1;/*正常情况下直接设定行动模式为觅食*/
}

/*动作，生物一个回合内所作的全部动作都在这里*/
void Creature::action()
{
	
	situation();/*计算生理情况，并确定搜索对象*/
	if (m_flag.live == 2)
	{
		return;
	}/*如果死亡则退出函数*/
	choose_target_race(m_flag.mode);
	search();

	switch (this->m_flag.mode)/*根据行动模式标志确定做什么,1为捕食2为生殖3为逃避0为什么都不做*/
	{
	case 1:
		move_to(*m_target.self);/*向目标移动*/
		eat(*m_target.self);
		break;
	case 2:
		move_to(*m_target.self);/*向目标移动*/
		breed();

		break;
	case 3:
		move_out(*m_target.self);/*远离目标*/
		break;
	default:
		move_to();
		break;
	}
	m_target = {};/*完成后重定义target结构体将其复位*/
}

void Creature::choose_target_race(int mode) {}

/*向某个对象移动，还需要一个变量来确定移动的数值是正还是负，要理一下逻辑*/
void Creature::move_to(Creature& c)
{
	if (m_target.distance <= m_step)/*距离小于移动距离则直接移动过去*/
	{
		m_position.x = c.m_position.x;
		m_position.y = c.m_position.y;
		m_target.contact = 1;/*接触到了目标*/
	}
	else/*如果距离不够则计算k并向该方向移动*/
	{
		m_position.x += m_step * m_target.distance_x;
		m_position.y += m_step * m_target.distance_y * m_target.k;
		m_target.contact = 0;/*由于没有接触到目标，所以将contact改为3,eat和breed要先判断contact的值*/
	}
}
/*随机移动，需要确定怎么生成随机值*/
void Creature::move_to()
{
	int temp_x = rand() % 20 - 10;
	int temp_y = rand() % 20 - 10;
	int temp_k = 0;/*方向*/
	if (temp_x != 0)
	{
		int temp_k = temp_y / temp_x;
	}
	m_position.x += m_step * (rand() % 2 - 1);
	m_position.y += m_step * (rand() % 2 - 1) * temp_k;
	m_target.contact = 0;
}

void Creature::move_out(Creature& c)/*远离，所以说是-=*/
{
	int temp_mov = m_step;
	m_position.x -= temp_mov * m_target.distance_x;
	m_position.y -= temp_mov * m_target.distance_y * m_target.k;
}
/*搜索，遍历目标种族，*/
void Creature::search()
{
	for (int i = 1; i <= *m_target.num; i++)
	{
		Creature* c = nullptr;
		c = m_target.race[i];
		if (c != nullptr && i != m_name)/*避免访问空指针，避免将自己作为目标*/
		{
			judge(*c);
		}
	}
	if (m_target.self == nullptr)/*如果搜索一圈后没有结果，则行动模式改为闲逛*/
	{
		m_flag.mode = 0;
	}
}
/*进食*/
void Creature::eat(Creature& c)
{
	if (m_target.contact == 1)
	{
		m_hunger += c.m_hp;
		c.m_hp = 0;
		c.m_flag.dead = 2;/*对象生物先改标签和血量，到它的Situation再清理*/
		m_flag.can_eat = 2;/*死掉的对象不能吃*/
		record(c);
	}
}
/*繁衍*/
void Creature::breed()
{
	if (m_target.contact == 1)
	{
		m_hp -= 50;
		if (m_flag.gender == 2)
		{
			*m_target.num += 1;/*总数往后播一位*/
			switch (this->m_flag.race)
			{
			case 1:
				m_target.race[*m_target.num] = new Wolf(*m_target.num, m_position.x, m_position.y, m_target.self->m_flag);
				break;
			case 2:
				m_target.race[*m_target.num] = new Sheep(*m_target.num, m_position.x, m_position.y, m_target.self->m_flag);
				break;
			default:
				break;
			}
						
			record(*this, *m_target.num);
		}
	}
}

void Creature::judge(Creature &c)
{
	
	if (c.m_position.x <= m_position.x + m_sight || c.m_position.x >= m_position.x - m_sight)
	{
		if (c.m_position.y <= m_position.y + m_sight || c.m_position.y >= m_position.y - m_sight)
		{
			switch (m_flag.mode)/*根据情况改变判断条件*/
			{
			case 1:/*捕食时需要对方能被捕食*/
				if (m_flag.can_eat == 1)
				{
					get_distance(c);
				}
				break;
			case 2:/*繁衍时需要对方为异性并同样处于繁衍状态*/
				if (m_flag.gender != c.m_flag.gender || c.m_flag.mode == 2)
				{
					get_distance(c);
				}
				break;
			default:
				break;
			}
		}
	}
}

void Creature::get_distance(Creature& c)/*计算距离，如果距离小于最短距离则更换对象*/
{
	int temp_x, temp_y, temp_distance;
	temp_x = c.m_position.x - m_position.x;
	temp_y = c.m_position.y - m_position.y;
	if (temp_x < 0)
	{
		m_target.distance_x = -1;
	}
	if (temp_y < 0)
	{
		m_target.distance_y = -1;
	}
	temp_distance = temp_x * temp_x + temp_y * temp_y;
	if (temp_distance <= m_target.distance)
	{
		m_target.self = &c;/*对象*/
		m_target.distance = temp_distance;
		
		if (temp_x == 0)
		{
			m_target.k = 0;
		}
		else
		{
			m_target.k = temp_y / temp_x;/*方向*/
		}
		
	}
}
/*记录死亡事件*/
void Creature::record()
{
	nature.events[nature.temp_events] = new Events(nature.time_past, m_position, m_name, m_flag.race);
	nature.events[nature.temp_events]->get(m_flag.dead);
	nature.temp_events++;
	nature.num.events++;
}
/*记录捕食事件*/
void Creature::record(Creature& c)
{

}
/*记录繁衍时间*/
void Creature::record(Creature& c, int name)
{
	nature.events[nature.temp_events] = new Events(nature.time_past, m_position, m_name, m_flag.race);
	nature.events[nature.temp_events]->get(c, m_target.self->m_name);
	nature.temp_events++;
	nature.num.events++;
}

